// Creates an array of fixed size and "Shifts" new elements as appropriate

using System;
using System.Collections;
using System.Collections.Generic;

namespace RLibrary
{
    /// <summary>
    /// A list that will shift elements down the array like a timeline.
    /// 
    /// (i = item, p = position)
    /// Enqueue one: i0 -> p0
    /// Enqueue another: i0 -> p1, i1 -> p0
    /// Enqueue another: i0 -> p2, i1 -> p1, i2 -> p0
    /// etc.
    /// </summary>
    /// <typeparam name="T">Type of item to be enqueued.</typeparam>
    public class ShiftList<T> : IEnumerable<T>
    {
        private T[] Items;
        private int MaxCount;
        public int Count;

        public ShiftList(int MaxSize) {
            Items = new T[MaxSize];
            MaxCount = MaxSize;
            Count = 0;
        }

        public void Enlist(T Item)
        {
            if (Count != MaxCount) Count++;
            for (int cCount = (Count - 1); cCount > 0; cCount--)
            {
                if (cCount == 0) break;
                Items[cCount] = Items[(cCount - 1)];
            }
            Items[0] = Item;
        }

        #region IEnumerable Members
        IEnumerator IEnumerable.GetEnumerator()
        {
            return new ShiftListEnum<T>(Items);
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return new ShiftListEnum<T>(Items);
        }
        #endregion
    }

    public class ShiftListEnum<T> : IEnumerator<T>
    {
        public T[] _MyItems;
        private int MyPosition = -1;

        public ShiftListEnum(T[] Items)
        {
            _MyItems = Items;
        }

        public object Current
        {
	        get { return _MyItems[MyPosition]; }
        }

        public bool MoveNext()
        {
 	        MyPosition++;
            return (MyPosition < _MyItems.Length);
        }

        public void Reset()
        {
 	        MyPosition = -1;
        }

        T IEnumerator<T>.Current
        {
            get { return _MyItems[MyPosition]; }
        }

        public void Dispose()
        {
            _MyItems = null;
        }

    }
}